package com.qf;

import java.util.HashMap;

/**
 * Hashmap的底层数据结构和工作原理是什么？
 *
 * 在hashmap内部，key和value是如何表示的？
 * 把key和value封装到了一个对象中，对象的属性包含key也包含value。
 *
 * 如何存放的？如何寻找数组的下标进行元素的插入
 *   (n - 1) & hash
 *   n是底层数组的长度（初始为16）
 *   hash是key计算出来的hash值
 *   等价于对数组长度进行取余运算
 *
 * 根据key计算出的hash值，对数组的长度进行取余数运算，得到数组的下标位置。
 *
 * （1） Hashmap底层数组的长度是多少？
 *      初始长度为 16， 初始的阈值 为 16*0.75=12 ，（当键值对的数量超过12时，就会触发resise()）
 * （2） 负载因子的初始值 为 0.75
 * （3） hashmap内部，是如何对key进行hash运算的
 *      (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
 *      如果key不为null，先取key自身的hashcode，右移动16位目的，使得原本的hashcode的高16位也可以影响最后的hash值
 * （4） hashmap的key能不能是null？ 能，key是null，key的hash值是0
 *
 * （5）如何出现hash冲突，是如何处理的？
 *      会在当前冲突的下标位置，形成链表
 *      如果链表的元素数量大于8，并且底层数组的长度至少为64，会把链表转换为红黑树
 *      如果底层数组长度不足64，那么会触发依次resize，把数组长度变为原来的两倍
 *
 * （6） TreeNode是咋回事？ hash冲突时，会先形成链表，如果链表的元素数量大于8，并且底层数组的长度至少为64，会把链表转换为红黑树
 *
 *
 *
 *
 */
public class HashMapDemo {

    public static void main(String[] args) {

        HashMap<Integer, String> map = new HashMap<>(64);

        map.put(1,"a");
        map.put(2,"b");
        map.put(3,"c");
        map.put(65,"d");
        map.put(129,"e");
        map.put(193,"f");
        map.put(257,"g");
        map.put(321,"h");
        map.put(385,"i");
        map.put(449,"j");
        map.put(513,"k");

        System.out.println(map);

//        String s = map.get(1);
//        System.out.println(s);
//
//        map.put(null,"abc");
//        map.put(1,"k");
    }

}
